package cn.careerx.app.common.models;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

public class ElasticSearch {
	
	private final static Logger logger = LoggerFactory.getLogger(ElasticSearch.class);
	
	private final static Map<String, Client> COMP_CLIENTS = new ConcurrentHashMap<>();
	
	private final static ReentrantLock initLock = new ReentrantLock();
	
	private static Config esServerConfs = null;
	
	static {
		InputStream is = Redis.class.getClassLoader().getResourceAsStream("es.conf");

		if(is != null){
			List<String> lines;
			try {
				lines = IOUtils.readLines(is, "utf-8");
				String lineSeparator = System.getProperty("line.separator");
				String confStr = StringUtils.join(lines, lineSeparator);
				esServerConfs = ConfigFactory.parseString(confStr);
			} catch (IOException e) {}
			finally{
				IOUtils.closeQuietly(is);
			}
		}
		
		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(Client client : COMP_CLIENTS.values()){
					client.close();
				}
			}
		}));
	}
	
	public static Client getClient(String component){
		Client ret = COMP_CLIENTS.get(component);
		if(ret == null){
			initLock.lock();
			try{
				ret = COMP_CLIENTS.get(component);
				if(ret == null){
					if(esServerConfs.hasPath(component)){
						Config conf = esServerConfs.getConfig(component);
						String esClusterName = conf.getString("esClusterName");
						List<String> esServerAddrs = conf.getStringList("serverAddrs");
								
						Settings settings = ImmutableSettings.settingsBuilder()
								.put("client.transport.sniff", true)
								.put("cluster.name", esClusterName)
				                .build();  

						TransportClient client = new TransportClient(settings);
						
						for(String addr : esServerAddrs){
							String[] parts = addr.split(":");
							client.addTransportAddress(new InetSocketTransportAddress(parts[0], Integer.parseInt(parts[1])));
						}
						
						ret = client;
						
						COMP_CLIENTS.put(component, client);
					}else{
						logger.error("Cannot find es config for component = "+component);
					}
				}
			}finally{
				initLock.unlock();
			}
		}
		
		return ret;
	}
	
	
	
}
